package mc0101.mccache.config;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.pool2.impl.GenericObjectPool;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisClusterConfiguration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisPassword;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.jedis.JedisConnection;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.connection.lettuce.LettucePoolingClientConfiguration;


@Slf4j
@Configuration
@ConditionalOnClass({ GenericObjectPool.class, JedisConnection.class })
public class LettuceFactoryConfig {

	private final RedisProperties properties;

//	@Value("${spring.redis.jedis.pool.soTimeout:3000}")
//	private String soTimeout;

	@Value("${spring.redis.jedis.pool.testOnBorrow:true}")
	private boolean testOnBorrow;

	@Value("${spring.redis.jedis.pool.testWhileIdle:true}")
	private boolean testWhileIdle;

	public LettuceFactoryConfig(RedisProperties properties) {
		this.properties = properties;
	}

//	@Bean
//	public JedisConnectionFactory redisConnectionFactory(){
//		if (properties.getJedis() == null || properties.getJedis().getPool() == null){
//			throw new RuntimeException("请检查jedis相关pool配置！");
//		}
//		JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
//		jedisPoolConfig.setTestOnBorrow(testOnBorrow);
//		jedisPoolConfig.setTestWhileIdle(testWhileIdle);
//		jedisPoolConfig.setMaxIdle(properties.getJedis().getPool().getMaxIdle());
//		jedisPoolConfig.setMinIdle(properties.getJedis().getPool().getMinIdle());
//		jedisPoolConfig.setMaxTotal(properties.getJedis().getPool().getMaxActive());
//		if (properties.getJedis().getPool().getMaxWait() != null) {
//			jedisPoolConfig.setMaxWaitMillis(properties.getJedis().getPool().getMaxWait().toMillis());
//		}
//
//		return new JedisConnectionFactory(getClusterConfiguration(),
//				CommonJedisClientConfiguration.create(jedisPoolConfig
//				, properties.getTimeout(), properties.getTimeout()));
//	}

    /**
     * 获取缓存连接
     *
     * @return
     */
    @Bean
    @Qualifier("lettuceConnectionFactory")
    public RedisConnectionFactory getConnectionFactory() {
        //单机模式
        RedisStandaloneConfiguration configuration = new RedisStandaloneConfiguration();
        configuration.setHostName(this.properties.getHost());
        configuration.setPort(this.properties.getPort());
        configuration.setDatabase(this.properties.getDatabase());
//        configuration.setPassword(RedisPassword.of(this.properties.getPassword()));
        //哨兵模式
        //RedisSentinelConfiguration configuration1 = new RedisSentinelConfiguration();
        //集群模式
        //RedisClusterConfiguration configuration2 = new RedisClusterConfiguration();
        LettuceConnectionFactory factory =
                new LettuceConnectionFactory(configuration, getPoolConfig());
        //factory.setShareNativeConnection(false);//是否允许多个线程操作共用同一个缓存连接，默认true，false时每个操作都将开辟新的连接
        return factory;
    }

	private RedisClusterConfiguration getClusterConfiguration() {
		if (this.properties.getCluster() == null) {
			throw new RuntimeException("请检查redis的cluster配置");
		}
		RedisProperties.Cluster clusterProperties = this.properties.getCluster();
		RedisClusterConfiguration config = new RedisClusterConfiguration(
				clusterProperties.getNodes());
		if (clusterProperties.getMaxRedirects() != null) {
			config.setMaxRedirects(clusterProperties.getMaxRedirects());
		}
		if (this.properties.getPassword() != null) {
			config.setPassword(RedisPassword.of(this.properties.getPassword()));
		}
		return config;
	}

    /**
     * 获取缓存连接池
     *
     * @return
     */
    @Bean
    public LettucePoolingClientConfiguration getPoolConfig() {
        GenericObjectPoolConfig config = new GenericObjectPoolConfig();
        config.setMaxTotal(this.properties.getLettuce().getPool().getMaxActive());
        config.setMaxWaitMillis(this.properties.getLettuce().getPool().getMaxWait().toMillis());
        config.setMaxIdle(this.properties.getLettuce().getPool().getMaxIdle());
        config.setMinIdle(this.properties.getLettuce().getPool().getMinIdle());
        LettucePoolingClientConfiguration pool = LettucePoolingClientConfiguration.builder()
                .poolConfig(config)
                .commandTimeout(this.properties.getTimeout())
                .shutdownTimeout(this.properties.getLettuce().getShutdownTimeout())
                .build();
        return pool;
    }

//	static class CommonJedisClientConfiguration implements JedisClientConfiguration {
//		private boolean useSsl;
//		private @Nullable
//		SSLSocketFactory sslSocketFactory;
//		private @Nullable
//		SSLParameters sslParameters;
//		private @Nullable
//		HostnameVerifier hostnameVerifier;
//		private boolean usePooling = true;
//		private GenericObjectPoolConfig poolConfig = new JedisPoolConfig();
//		private @Nullable String clientName;
//		private Duration readTimeout = Duration.ofMillis(Protocol.DEFAULT_TIMEOUT);
//		private Duration connectTimeout = Duration.ofMillis(Protocol.DEFAULT_TIMEOUT);
//
//		public static JedisClientConfiguration create(GenericObjectPoolConfig jedisPoolConfig, Duration readTimeout, Duration connectTimeout) {
//
//			CommonJedisClientConfiguration configuration = new CommonJedisClientConfiguration();
//			configuration.setPoolConfig(jedisPoolConfig);
//			if (readTimeout != null){
//				configuration.setReadTimeout(readTimeout);
//			}
//			if (connectTimeout != null){
//				configuration.setConnectTimeout(connectTimeout);
//			}
//			return configuration;
//		}
//
//		/* (non-Javadoc)
//		 * @see org.springframework.data.redis.connection.jedis.JedisClientConfiguration#isUseSsl()
//		 */
//		@Override
//		public boolean isUseSsl() {
//			return useSsl;
//		}
//
//		public void setUseSsl(boolean useSsl) {
//			this.useSsl = useSsl;
//		}
//
//		/*
//		 * (non-Javadoc)
//		 * @see org.springframework.data.redis.connection.jedis.JedisClientConfiguration#getSslSocketFactory()
//		 */
//		@Override
//		public Optional<SSLSocketFactory> getSslSocketFactory() {
//			return Optional.ofNullable(sslSocketFactory);
//		}
//
//		public void setSslSocketFactory(SSLSocketFactory sslSocketFactory) {
//			this.sslSocketFactory = sslSocketFactory;
//		}
//
//		/*
//		 * (non-Javadoc)
//		 * @see org.springframework.data.redis.connection.jedis.JedisClientConfiguration#getSslParameters()
//		 */
//		@Override
//		public Optional<SSLParameters> getSslParameters() {
//			return Optional.ofNullable(sslParameters);
//		}
//
//		public void setSslParameters(SSLParameters sslParameters) {
//			this.sslParameters = sslParameters;
//		}
//
//		/*
//		 * (non-Javadoc)
//		 * @see org.springframework.data.redis.connection.jedis.JedisClientConfiguration#getHostnameVerifier()
//		 */
//		@Override
//		public Optional<HostnameVerifier> getHostnameVerifier() {
//			return Optional.ofNullable(hostnameVerifier);
//		}
//
//		public void setHostnameVerifier(HostnameVerifier hostnameVerifier) {
//			this.hostnameVerifier = hostnameVerifier;
//		}
//
//		/*
//		 * (non-Javadoc)
//		 * @see org.springframework.data.redis.connection.jedis.JedisClientConfiguration#isUsePooling()
//		 */
//		@Override
//		public boolean isUsePooling() {
//			return usePooling;
//		}
//
//		public void setUsePooling(boolean usePooling) {
//			this.usePooling = usePooling;
//		}
//
//		/*
//		 * (non-Javadoc)
//		 * @see org.springframework.data.redis.connection.jedis.JedisClientConfiguration#getPoolConfig()
//		 */
//		@Override
//		public Optional<GenericObjectPoolConfig> getPoolConfig() {
//			return Optional.ofNullable(poolConfig);
//		}
//
//		public void setPoolConfig(GenericObjectPoolConfig poolConfig) {
//			this.poolConfig = poolConfig;
//		}
//
//		/*
//		 * (non-Javadoc)
//		 * @see org.springframework.data.redis.connection.jedis.JedisClientConfiguration#getClientName()
//		 */
//		@Override
//		public Optional<String> getClientName() {
//			return Optional.ofNullable(clientName);
//		}
//
//		public void setClientName(String clientName) {
//			this.clientName = clientName;
//		}
//
//		/*
//		 * (non-Javadoc)
//		 * @see org.springframework.data.redis.connection.jedis.JedisClientConfiguration#getReadTimeout()
//		 */
//		@Override
//		public Duration getReadTimeout() {
//			return readTimeout;
//		}
//
//		public void setReadTimeout(Duration readTimeout) {
//			this.readTimeout = readTimeout;
//		}
//
//		/*
//		 * (non-Javadoc)
//		 * @see org.springframework.data.redis.connection.jedis.JedisClientConfiguration#getConnectTimeout()
//		 */
//		@Override
//		public Duration getConnectTimeout() {
//			return connectTimeout;
//		}
//
//		public void setConnectTimeout(Duration connectTimeout) {
//			this.connectTimeout = connectTimeout;
//		}
//
//		public void setShardInfo(JedisShardInfo shardInfo) {
//
//			setSslSocketFactory(shardInfo.getSslSocketFactory());
//			setSslParameters(shardInfo.getSslParameters());
//			setHostnameVerifier(shardInfo.getHostnameVerifier());
//			setUseSsl(shardInfo.getSsl());
//			setConnectTimeout(Duration.ofMillis(shardInfo.getConnectionTimeout()));
//			setReadTimeout(Duration.ofMillis(shardInfo.getSoTimeout()));
//		}
//	}
}
